<script setup>
import { ref, onMounted, computed, watch, inject, toRaw } from 'vue'
import ObjectEditor from './ObjectEditor.vue'
import VersionObjectEditor from './VersionObjectEditor.vue'
import _ from 'lodash'

const props = defineProps({
    value: {
        type: Object,
        default: () => {}
    },
    paths: {
        type: Object,
        default: () => []
    }
})
const ids = inject('ids')
const isMerge = inject('isMerge')
const updateChangeValue = inject('updateChangeValue')
const keyLength = ref(0)

const properties = ref([])
const to = () => {
    properties.value.length = 0
    for (const key in props.value) {
        if (key.endsWith('--versions')) {
            continue
        }
        keyLength.value = Math.max(keyLength.value, key.length)
        const value = props.value[key]
        const versions = props.value[key + '--versions'] || []
        const checkeds = toRaw(versions).filter(it => ids.value.includes(it.id))
        const lastValue = checkeds.at(-1)?.value
        properties.value.push({
            isVisible: !isMerge.value || checkeds.length != 0,
            key,
            value: isMerge.value ? lastValue : value,
            hasVersions: !isMerge.value && checkeds.length != 0,
            versions: checkeds,
            component: isMerge.value ? VersionObjectEditor : ObjectEditor,
            keyEditable: false,
            keyNew: '',
            valueNew: '',
            valueEditable: false
        })
    }
}
watch(
    () => props.value,
    () => to()
)
watch(ids, () => to())
watch(isMerge, () => to())

const onEditKey = prop => {
    prop.keyEditable = true
    prop.keyNew = prop.key
    console.log('编辑key', prop)
}
const onSaveKey = prop => {
    prop.keyEditable = false
    prop.key = prop.keyNew
    keyLength.value = prop.key.length
    submit(prop, value)
}
const onEditValue = prop => {
    prop.valueEditable = true
    prop.valueNew = prop.value
    console.log('编辑Value', prop)
}
const onSaveValue = prop => {
    prop.valueEditable = false
    prop.value = prop.valueNew
    submit(prop.key, prop.value)
}
const submit = (prop, value) => {
    updateChangeValue(props.paths, prop, value)
}
</script>

<template>
    <div>
        <div class="prop-item" v-for="prop in properties" :key="props.key">
            <div v-if="prop.isVisible">
                <div class="prop">
                    <div class="prop-key" @dblclick="onEditKey(prop)">
                        <n-input
                            v-if="prop.keyEditable"
                            v-model:value="prop.keyNew"
                            type="text"
                            size="small"
                            style="width: 100px"
                            placeholder="小"
                            @blur="onSaveKey(prop)" />
                        <div v-else :style="{ width: keyLength * 16 + 'px' }">{{ prop.key }}:</div>
                    </div>
                    <div class="prop-value">
                        <div class="prop-value-current object" v-if="_.isPlainObject(prop.value)">
                            <component
                                :is="prop.component"
                                :value="prop.value"
                                :paths="[...paths, prop.key]"></component>
                        </div>
                        <div class="prop-value-current" v-else-if="_.isArray(prop.value)">
                            <div v-for="item in prop.value">
                                <component :is="prop.component" :value="item"></component>
                            </div>
                        </div>
                        <div class="prop-value-current" v-else @dblclick="onEditValue(prop)">
                            <n-input
                                v-if="prop.valueEditable"
                                v-model:value="prop.valueNew"
                                type="text"
                                size="small"
                                @blur="onSaveValue(prop)"
                                placeholder="小" />
                            <div v-else>{{ prop.value }}</div>
                        </div>
                    </div>
                </div>
                <div
                    class="prop-versions"
                    :style="{ marginLeft: keyLength * 16 + 16 + 'px' }"
                    v-if="prop.hasVersions">
                    <n-collapse>
                        <n-collapse-item title="修改历史">
                            <n-timeline>
                                <n-timeline-item
                                    v-for="(version, index) in prop.versions"
                                    type="warning"
                                    :title="version.id"
                                    :time="version.time">
                                    <div class="xx">
                                        <div class="flex-1">
                                            <VersionObjectEditor
                                                v-if="_.isObject(version.value)"
                                                :value="version.value" />
                                            <div v-else>
                                                {{ version.value }}
                                            </div>
                                        </div>
                                        <!-- <div>{{ version.id }}</div> -->
                                    </div>
                                    <template #footer>
                                        {{ version.time }}
                                        <n-tag type="info" size="small" v-if="version.user">
                                            {{ version.user }}
                                        </n-tag>
                                    </template>
                                </n-timeline-item>
                            </n-timeline>
                        </n-collapse-item>
                    </n-collapse>
                </div>
            </div>
        </div>
    </div>
</template>

<style scoped>
.prop-item {
    border-bottom: 1px solid red;
}
.prop {
    display: flex;
    justify-content: flex-start;
    align-items: center;
    gap: 16px;
}
.prop-key {
    /* width: 100px; */
    font-size: 16px;
}

.prop-value {
    flex: 1;
}
.prop-value-current {
    padding: 0px 8px;
    display: flex;
    /* border-left: 1px solid red; */
}
.prop-versions {
    margin-top: 8px;
    /* border-left: 1px solid red; */
}

.xx {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 16px;
}

.flex-1 {
    flex: 1;
}
.object {
    position: relative;
}
.brace {
    width: 20px; /* 大括号的宽度 */
    height: 100%; /* 高度自适应 */
    margin-right: 10px; /* 大括号和内容之间的间距 */
}
</style>
